package com.wyj.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyServer {
    public static void main(String[] args) throws InterruptedException {
        //1、创建bossGroup线程组，处理连接事件。默认线程数为2*处理器线程数
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //    2、创建workGroup线程组，处理读写事件。默认线程组数量为2*处理器线程数
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        //    3、创建服务端启动助手
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //    4、设置启动助手
        serverBootstrap.group(bossGroup, workerGroup)
                //5、设置服务端通道的实现类
                .channel(NioServerSocketChannel.class)
                //6、设置服务端队列的线程数
                //存放已经完成三次握手的请求队列的最大长度，未设置或者小于1，Java默认值是50；大于设置的最大值，会报错；
                .option(ChannelOption.SO_BACKLOG, 128)
                //7、设置活跃状态.child设置的workerGroup中的线程
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                //8、创建一个通道初始化对
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        //    9、向pipeline添加自定义的处理类
                        // socketChannel.pipeline().addLast(new MessageDecoder());
                        // socketChannel.pipeline().addLast(new MessageEncoder());
                        socketChannel.pipeline().addLast(new MessageCoder());
                        socketChannel.pipeline().addLast(new NettyServerHandler());

                    }
                });
        //    10、启动服务端并且绑定端口，同时将异步操作改为同步 .sync()
        ChannelFuture channelFuture = serverBootstrap.bind("127.0.0.1", 19999);
        channelFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture1) throws Exception {
                if (channelFuture1.isSuccess()){
                    System.out.println("【端口绑定启动成功】");
                }else{
                    System.out.println("【端口绑定失败了】");
                }
            }
        });
        System.out.println("【服务端启动成功】");
        //    11、关闭通道和关闭连接池。并不是真正意义上的关闭，而是监听通道关闭状态。
        channelFuture.channel().closeFuture().sync();
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}
